﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;


namespace Atosenet.Protocol
{
    public abstract class ProtocolPacket : IProtocolPacket
    {
        #region 成员



        #endregion


        #region 初始化

        public ProtocolPacket()
        { }

        #endregion


        #region 公开函数

        public abstract void Append(byte[] data, ref int offset);

        public abstract byte[] Generate();

        public abstract void Reset();
                
        #endregion


        #region 静态函数

        public static bool IsNullOrInvalid(IProtocolPacket packet)
        {
            if (packet == null)
                return true;

            return !packet.IsValid || !packet.IsCompleted;
        }

        public static ProtocolPacket CreateInstance(string protocolName)
        {
            if (TypeManager.Plugins.Count == 0 || String.IsNullOrEmpty(protocolName))
                return null;

            return TypeManager.CreateInstance(protocolName, null) as ProtocolPacket;
        }

        public static bool TryCreateInstance(string protocolName, out ProtocolPacket result)
        {
            result = CreateInstance(protocolName);
            return result != null;
        }

        public static ProtocolPacket CreatePacket(string protocolName, params object[] args)
        {
            ProtocolPacket pkt = null;

            if (!TryCreateInstance(protocolName, out pkt))
                return null;

            return TypeManager.InvokeStaticMethod(pkt, "CreatePacket", args) as ProtocolPacket;
        }

        #endregion


        #region 事件

        /* Packet Header Identify Code */
        public abstract byte[] PacketFlag 
        {
            get;
        }

        public int DataLength
        {
            get 
            {
                if (RawData == null)
                    return 0;

                return RawData.Length;
            }
        }

        public abstract bool IsCompleted
        {
            get;
        }

        public abstract string PacketDataHex
        {
            get;
        }

        public abstract bool HasError
        {
            get;
        }

        public abstract bool IsValid
        {
            get;
        }

        public abstract byte[] RawData
        {
            get;
        }

        public abstract DateTime Timestamp
        {
            get;
        }

        #endregion


        #region ICloneable 成员

        public abstract object Clone();

        #endregion
    }
}
